package com.danco.training.zaneuskaya.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.danco.training.zaneuskaya.domain.Event;
import com.danco.training.zaneuskaya.domain.User;
import com.danco.training.zaneuskaya.repository.EventDao;
import com.danco.training.zaneuskaya.repository.UserDao;
import com.danco.training.zaneuskaya.service.EventService;
import com.danco.training.zaneuskaya.service.exception.UserException;

/**
 * @author Zaneuskaya Aliaksandra
 *
 */
@Service("eventService")
@Transactional
public class EventServiceImpl implements EventService {

	private static final String EVENT_IS_NULL = "Event is null";

	private static final String EVENT_ALREADY_EXISTS = "Event already exists";

	private static final Logger logger = Logger
			.getLogger(EventServiceImpl.class);

	@Autowired
	private EventDao eventDao;

	@Autowired
	private UserDao userDao;

	public EventDao getEventDao() {
		return eventDao;
	}

	public void setEventDao(EventDao eventDao) {
		this.eventDao = eventDao;
	}

	public UserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	@Override
	public void createEntity(Event t)  {
		try {
			if(eventDao.findEventsByTitle(t.getEventTitle()) == null){
				eventDao.create(t);
		}
		else{
			throw new UserException(EVENT_ALREADY_EXISTS);
		}
	
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (UserException e) {
			logger.error(e.getMessage(), e);
		}catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		} 

	}

	@Override
	public void deleteEntityById(Integer id) {
		try {
			Event event = eventDao.read(id);

			eventDao.delete(event);

		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}

	}

	@Override
	public void updateEntity(Event t) {
		try {
			Event event = eventDao.read(t.getEventId());
			event.setEventAccess(t.getEventAccess());
			event.setEventAddress(t.getEventAddress());
			event.setEventCity(t.getEventCity());
			event.setEventCountry(t.getEventCountry());
			event.setEventDescription(t.getEventDescription());
			event.setEventStartDate(t.getEventStartDate());
			event.setEventEndDate(t.getEventEndDate());
			event.setEventTitle(t.getEventTitle());
			eventDao.update(event);
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}

	}

	@Override
	public Event getEntityById(Integer id) {
		Event event = null;
		try {
			event = eventDao.read(id);
			if (event == null) {
				throw new NullPointerException(EVENT_IS_NULL);
			}
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}
		return event;
	}

	@Override
	public List<Event> getEntityList() {
		List<Event> events = null;
		try {
			events = eventDao.readAll();
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}
		return events;
	}

	@Override
	public List<Event> getUserEventList(User user) {
		List<Event> events = null;
		try {
			user = userDao.read(user.getUserId());
			events = new ArrayList<Event>(user.getEvents());
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}
		return events;
	}

	@Override
	public void addEventParticipant(Event event, User user) {
		try {
			user = userDao.read(user.getUserId());
			event = eventDao.read(event.getEventId());
			event.getParticipants().add(user);
		
			eventDao.update(event);
			
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}

	}

	@Override
	public void removeEventParticipant(Event event, User user) {
		try {
			user = userDao.read(user.getUserId());
			event = eventDao.read(event.getEventId());
		
			event.getParticipants().remove(user);
			eventDao.update(event);
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}

	}

	@Override
	public boolean isParticipant(Event event, User user) {
		try {
			user = userDao.read(user.getUserId());
			event = eventDao.read(event.getEventId());
		if (user == null || event == null){
			throw new NullPointerException();
		}
		else{
			return event.getParticipants().contains(user);
		}
			
		} catch (NullPointerException e) {
			logger.error(e.getMessage(), e);
		} catch (HibernateException e) {
			logger.error(e.getMessage(), e);
		}
		return false;
	}

}
